package com.raj.sample;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.CommunityTarget;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
   
public class Snmpwalk implements CommandResponder {   
    private MultiThreadedMessageDispatcher dispatcher;      
    private Snmp snmp = null;      
    private Address listenAddress;      
    private ThreadPool threadPool;    
    
    private String targetAddr;
	  private String oidStr;
	  private String commStr;
	  private int snmpVersion;
	  private String portNum;  
	  private List<VariableBinding> walkResponseList;
    /**  
     * @param args  
     */   
    public Snmpwalk() {      
    	
        // BasicConfigurator.configure();      
    }      
    public Snmpwalk(HashMap<String, String> values){
        targetAddr = values.get("ipaddr");
        oidStr = values.get("oid");
  	  commStr = values.get("communityString");
  	  int tempVersion = Integer.parseInt(values.get("version"));
  	  if(tempVersion == 1){
  		  snmpVersion = SnmpConstants.version1;
  	  }
  	  if(tempVersion == 2){
  		  snmpVersion = SnmpConstants.version2c;
  	  }
  	  if(tempVersion == 3){
  		  snmpVersion = SnmpConstants.version3;
  	  }
  	  portNum =  "161";
    }	
    
    private void init() throws UnknownHostException, IOException {    
    	walkResponseList = new ArrayList<VariableBinding>();
        threadPool = ThreadPool.create("Trap", 2);      
        dispatcher = new MultiThreadedMessageDispatcher(threadPool,new MessageDispatcherImpl());
        
        
        CommunityTarget target = new CommunityTarget();
		target.setCommunity(new OctetString(commStr));
		target.setAddress(new UdpAddress(targetAddr + "/" + portNum));
		if(snmpVersion==0)
		target.setVersion(SnmpConstants.version1);
		else if(snmpVersion==1){target.setVersion(SnmpConstants.version2c);}
		else{target.setVersion(SnmpConstants.version3);}
		target.setTimeout(3000);
		target.setRetries(3);
		
		
		PDU pdu = new PDU();
		ResponseEvent response;
		pdu.add(new VariableBinding(new OID(oidStr)));
		pdu.setType(PDU.GET);

		       
        //TransportMapping transport = new DefaultUdpTransportMapping(new UdpAddress(targetAddr + "/" + portNum));
        TransportMapping transport = new DefaultUdpTransportMapping();
        snmp = new Snmp(dispatcher, transport);      
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());      
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());      
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());      
        USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);      
        SecurityModels.getInstance().addSecurityModel(usm);      
        snmp.listen();      
        snmp.getMessageDispatcher().sendPdu(target, pdu, true);
    }      
    public void run() {      
        try {      
            init();      
            snmp.addCommandResponder(this);      
            System.out.println("Processing...");      
        } catch (Exception ex) {      
            ex.printStackTrace();      
        }      
    }      
   
    
    public void processPdu(CommandResponderEvent respEvnt) {   
    	VariableBinding vb = null;
    	PDU responsePDU = respEvnt.getPDU();
    	if (responsePDU != null) {
			vb = responsePDU.get(0);
		}
    	
    	boolean finished = false;

		while (!finished) {
    	
    	if (responsePDU == null) {
			finished = true;
		} else if (responsePDU.getErrorStatus() != 0) {
			finished = true;
		} else if (vb.getOid() == null) {
			finished = true;
		} else {
			walkResponseList.add(vb);		}
    	
    	if (walkResponseList.size() == 0) {
			System.out.println("SNMP Walk Failed , " + oidStr
					+ " is not configured for " + targetAddr);
		} else {
			System.out.println("Response List size for " + targetAddr + ": "
					+ walkResponseList.size());
		}

		String resData = "";
		for (VariableBinding vbdata : walkResponseList) {
			resData += vb.getOid() + ":=" + vb.getVariable().toString()
					+ "\r\n";
		}
		//Logger.logMessage(resData);
		System.out.println(resData);
		
	}
    	
    	
    	
    	
		}
		
		
}